{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\statsmodels\\compat\\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.\n",
      "  from pandas.core import datetools\n"
     ]
    }
   ],
   "source": [
    "# 分组级运算和转换\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import statsmodels.api as sm\n",
    "from pandas import DataFrame, Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>data1</th>\n",
       "      <th>data2</th>\n",
       "      <th>key1</th>\n",
       "      <th>key2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.307825</td>\n",
       "      <td>0.217729</td>\n",
       "      <td>a</td>\n",
       "      <td>one</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.623577</td>\n",
       "      <td>-0.902720</td>\n",
       "      <td>a</td>\n",
       "      <td>two</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.038196</td>\n",
       "      <td>-1.206849</td>\n",
       "      <td>b</td>\n",
       "      <td>one</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.736848</td>\n",
       "      <td>0.690690</td>\n",
       "      <td>b</td>\n",
       "      <td>two</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.267622</td>\n",
       "      <td>-0.203043</td>\n",
       "      <td>a</td>\n",
       "      <td>one</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      data1     data2 key1 key2\n",
       "0  0.307825  0.217729    a  one\n",
       "1  0.623577 -0.902720    a  two\n",
       "2 -0.038196 -1.206849    b  one\n",
       "3  0.736848  0.690690    b  two\n",
       "4 -0.267622 -0.203043    a  one"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],\n",
    "                'key2' : ['one', 'two', 'one', 'two', 'one'],\n",
    "                'data1' : np.random.randn(5),\n",
    "                'data2' : np.random.randn(5)})\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mean_data1</th>\n",
       "      <th>mean_data2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>key1</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>a</th>\n",
       "      <td>0.221260</td>\n",
       "      <td>-0.296011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>b</th>\n",
       "      <td>0.349326</td>\n",
       "      <td>-0.258079</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      mean_data1  mean_data2\n",
       "key1                        \n",
       "a       0.221260   -0.296011\n",
       "b       0.349326   -0.258079"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "k1_means = df.groupby('key1').mean().add_prefix('mean_')\n",
    "k1_means"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>data1</th>\n",
       "      <th>data2</th>\n",
       "      <th>key1</th>\n",
       "      <th>key2</th>\n",
       "      <th>mean_data1</th>\n",
       "      <th>mean_data2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.307825</td>\n",
       "      <td>0.217729</td>\n",
       "      <td>a</td>\n",
       "      <td>one</td>\n",
       "      <td>0.221260</td>\n",
       "      <td>-0.296011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.623577</td>\n",
       "      <td>-0.902720</td>\n",
       "      <td>a</td>\n",
       "      <td>two</td>\n",
       "      <td>0.221260</td>\n",
       "      <td>-0.296011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.267622</td>\n",
       "      <td>-0.203043</td>\n",
       "      <td>a</td>\n",
       "      <td>one</td>\n",
       "      <td>0.221260</td>\n",
       "      <td>-0.296011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.038196</td>\n",
       "      <td>-1.206849</td>\n",
       "      <td>b</td>\n",
       "      <td>one</td>\n",
       "      <td>0.349326</td>\n",
       "      <td>-0.258079</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.736848</td>\n",
       "      <td>0.690690</td>\n",
       "      <td>b</td>\n",
       "      <td>two</td>\n",
       "      <td>0.349326</td>\n",
       "      <td>-0.258079</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      data1     data2 key1 key2  mean_data1  mean_data2\n",
       "0  0.307825  0.217729    a  one    0.221260   -0.296011\n",
       "1  0.623577 -0.902720    a  two    0.221260   -0.296011\n",
       "4 -0.267622 -0.203043    a  one    0.221260   -0.296011\n",
       "2 -0.038196 -1.206849    b  one    0.349326   -0.258079\n",
       "3  0.736848  0.690690    b  two    0.349326   -0.258079"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df, k1_means, left_on='key1', right_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>c</th>\n",
       "      <th>d</th>\n",
       "      <th>e</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Joe</th>\n",
       "      <td>-0.575573</td>\n",
       "      <td>-0.264966</td>\n",
       "      <td>0.402191</td>\n",
       "      <td>-0.626705</td>\n",
       "      <td>2.266715</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Steve</th>\n",
       "      <td>-2.293446</td>\n",
       "      <td>0.989424</td>\n",
       "      <td>0.447412</td>\n",
       "      <td>0.779285</td>\n",
       "      <td>0.527718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wes</th>\n",
       "      <td>-1.609951</td>\n",
       "      <td>0.807645</td>\n",
       "      <td>1.383784</td>\n",
       "      <td>-0.402235</td>\n",
       "      <td>1.071397</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Jim</th>\n",
       "      <td>0.401508</td>\n",
       "      <td>0.044202</td>\n",
       "      <td>-0.000760</td>\n",
       "      <td>-0.452882</td>\n",
       "      <td>-1.295740</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Travis</th>\n",
       "      <td>-0.097253</td>\n",
       "      <td>0.896917</td>\n",
       "      <td>0.176152</td>\n",
       "      <td>0.507412</td>\n",
       "      <td>1.666385</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               a         b         c         d         e\n",
       "Joe    -0.575573 -0.264966  0.402191 -0.626705  2.266715\n",
       "Steve  -2.293446  0.989424  0.447412  0.779285  0.527718\n",
       "Wes    -1.609951  0.807645  1.383784 -0.402235  1.071397\n",
       "Jim     0.401508  0.044202 -0.000760 -0.452882 -1.295740\n",
       "Travis -0.097253  0.896917  0.176152  0.507412  1.666385"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people = DataFrame(np.random.randn(5, 5),\n",
    "                   columns=['a', 'b', 'c', 'd', 'e'],\n",
    "                   index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])\n",
    "people"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>c</th>\n",
       "      <th>d</th>\n",
       "      <th>e</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>one</th>\n",
       "      <td>-0.760926</td>\n",
       "      <td>0.479865</td>\n",
       "      <td>0.654042</td>\n",
       "      <td>-0.173843</td>\n",
       "      <td>1.668165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>-0.945969</td>\n",
       "      <td>0.516813</td>\n",
       "      <td>0.223326</td>\n",
       "      <td>0.163202</td>\n",
       "      <td>-0.384011</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            a         b         c         d         e\n",
       "one -0.760926  0.479865  0.654042 -0.173843  1.668165\n",
       "two -0.945969  0.516813  0.223326  0.163202 -0.384011"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "key = ['one', 'two', 'one', 'two', 'one'] # 每一行的名称\n",
    "people.groupby(key).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>c</th>\n",
       "      <th>d</th>\n",
       "      <th>e</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Joe</th>\n",
       "      <td>-0.760926</td>\n",
       "      <td>0.479865</td>\n",
       "      <td>0.654042</td>\n",
       "      <td>-0.173843</td>\n",
       "      <td>1.668165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Steve</th>\n",
       "      <td>-0.945969</td>\n",
       "      <td>0.516813</td>\n",
       "      <td>0.223326</td>\n",
       "      <td>0.163202</td>\n",
       "      <td>-0.384011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wes</th>\n",
       "      <td>-0.760926</td>\n",
       "      <td>0.479865</td>\n",
       "      <td>0.654042</td>\n",
       "      <td>-0.173843</td>\n",
       "      <td>1.668165</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Jim</th>\n",
       "      <td>-0.945969</td>\n",
       "      <td>0.516813</td>\n",
       "      <td>0.223326</td>\n",
       "      <td>0.163202</td>\n",
       "      <td>-0.384011</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Travis</th>\n",
       "      <td>-0.760926</td>\n",
       "      <td>0.479865</td>\n",
       "      <td>0.654042</td>\n",
       "      <td>-0.173843</td>\n",
       "      <td>1.668165</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               a         b         c         d         e\n",
       "Joe    -0.760926  0.479865  0.654042 -0.173843  1.668165\n",
       "Steve  -0.945969  0.516813  0.223326  0.163202 -0.384011\n",
       "Wes    -0.760926  0.479865  0.654042 -0.173843  1.668165\n",
       "Jim    -0.945969  0.516813  0.223326  0.163202 -0.384011\n",
       "Travis -0.760926  0.479865  0.654042 -0.173843  1.668165"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "people.groupby(key).transform(np.mean) # transform变回原来形状，但是用前面分组聚合的值填空。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>c</th>\n",
       "      <th>d</th>\n",
       "      <th>e</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Joe</th>\n",
       "      <td>0.185353</td>\n",
       "      <td>-0.744831</td>\n",
       "      <td>-0.251851</td>\n",
       "      <td>-0.452862</td>\n",
       "      <td>0.598549</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Steve</th>\n",
       "      <td>-1.347477</td>\n",
       "      <td>0.472611</td>\n",
       "      <td>0.224086</td>\n",
       "      <td>0.616084</td>\n",
       "      <td>0.911729</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wes</th>\n",
       "      <td>-0.849026</td>\n",
       "      <td>0.327780</td>\n",
       "      <td>0.729741</td>\n",
       "      <td>-0.228392</td>\n",
       "      <td>-0.596769</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Jim</th>\n",
       "      <td>1.347477</td>\n",
       "      <td>-0.472611</td>\n",
       "      <td>-0.224086</td>\n",
       "      <td>-0.616084</td>\n",
       "      <td>-0.911729</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Travis</th>\n",
       "      <td>0.663673</td>\n",
       "      <td>0.417051</td>\n",
       "      <td>-0.477890</td>\n",
       "      <td>0.681254</td>\n",
       "      <td>-0.001781</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               a         b         c         d         e\n",
       "Joe     0.185353 -0.744831 -0.251851 -0.452862  0.598549\n",
       "Steve  -1.347477  0.472611  0.224086  0.616084  0.911729\n",
       "Wes    -0.849026  0.327780  0.729741 -0.228392 -0.596769\n",
       "Jim     1.347477 -0.472611 -0.224086 -0.616084 -0.911729\n",
       "Travis  0.663673  0.417051 -0.477890  0.681254 -0.001781"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def demean(arr):\n",
    "    return arr - arr.mean()\n",
    "demeaned = people.groupby(key).transform(demean) # \n",
    "demeaned"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>c</th>\n",
       "      <th>d</th>\n",
       "      <th>e</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>one</th>\n",
       "      <td>-3.700743e-17</td>\n",
       "      <td>3.700743e-17</td>\n",
       "      <td>7.401487e-17</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-1.480297e-16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>two</th>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>2.775558e-17</td>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.000000e+00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                a             b             c    d             e\n",
       "one -3.700743e-17  3.700743e-17  7.401487e-17  0.0 -1.480297e-16\n",
       "two  0.000000e+00  2.775558e-17  0.000000e+00  0.0  0.000000e+00"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "demeaned.groupby(key).mean() # 因为前面每个值都减去了平均值，所以应该是0。显示不为0是因为浮点数计算误差。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# apply：一般性的“拆分－应用－合并”"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>total_bill</th>\n",
       "      <th>tip</th>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th>time</th>\n",
       "      <th>size</th>\n",
       "      <th>tip_pct</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>16.99</td>\n",
       "      <td>1.01</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.059447</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>10.34</td>\n",
       "      <td>1.66</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "      <td>0.160542</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>21.01</td>\n",
       "      <td>3.50</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "      <td>0.166587</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>23.68</td>\n",
       "      <td>3.31</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.139780</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>24.59</td>\n",
       "      <td>3.61</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>4</td>\n",
       "      <td>0.146808</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   total_bill   tip smoker  day    time  size   tip_pct\n",
       "0       16.99  1.01     No  Sun  Dinner     2  0.059447\n",
       "1       10.34  1.66     No  Sun  Dinner     3  0.160542\n",
       "2       21.01  3.50     No  Sun  Dinner     3  0.166587\n",
       "3       23.68  3.31     No  Sun  Dinner     2  0.139780\n",
       "4       24.59  3.61     No  Sun  Dinner     4  0.146808"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tips = pd.read_csv('../data/tips.csv')\n",
    "tips['tip_pct'] = tips['tip'] / tips['total_bill'] # 新加一列，小费与账单金额的比例。\n",
    "tips.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>total_bill</th>\n",
       "      <th>tip</th>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th>time</th>\n",
       "      <th>size</th>\n",
       "      <th>tip_pct</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>67</th>\n",
       "      <td>3.07</td>\n",
       "      <td>1.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>1</td>\n",
       "      <td>0.325733</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>178</th>\n",
       "      <td>9.60</td>\n",
       "      <td>4.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.416667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>172</th>\n",
       "      <td>7.25</td>\n",
       "      <td>5.15</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.710345</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     total_bill   tip smoker  day    time  size   tip_pct\n",
       "67         3.07  1.00    Yes  Sat  Dinner     1  0.325733\n",
       "178        9.60  4.00    Yes  Sun  Dinner     2  0.416667\n",
       "172        7.25  5.15    Yes  Sun  Dinner     2  0.710345"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def top(df, n=5, column='tip_pct'):\n",
    "    return df.sort_values(by=column)[-n:] # 获取小费比例最高的n条数据\n",
    "top(tips, n=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>total_bill</th>\n",
       "      <th>tip</th>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th>time</th>\n",
       "      <th>size</th>\n",
       "      <th>tip_pct</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>smoker</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">No</th>\n",
       "      <th>149</th>\n",
       "      <td>7.51</td>\n",
       "      <td>2.00</td>\n",
       "      <td>No</td>\n",
       "      <td>Thur</td>\n",
       "      <td>Lunch</td>\n",
       "      <td>2</td>\n",
       "      <td>0.266312</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>232</th>\n",
       "      <td>11.61</td>\n",
       "      <td>3.39</td>\n",
       "      <td>No</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.291990</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">Yes</th>\n",
       "      <th>178</th>\n",
       "      <td>9.60</td>\n",
       "      <td>4.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.416667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>172</th>\n",
       "      <td>7.25</td>\n",
       "      <td>5.15</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.710345</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            total_bill   tip smoker   day    time  size   tip_pct\n",
       "smoker                                                           \n",
       "No     149        7.51  2.00     No  Thur   Lunch     2  0.266312\n",
       "       232       11.61  3.39     No   Sat  Dinner     2  0.291990\n",
       "Yes    178        9.60  4.00    Yes   Sun  Dinner     2  0.416667\n",
       "       172        7.25  5.15    Yes   Sun  Dinner     2  0.710345"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tips.groupby('smoker').apply(top, n=2, column='tip_pct') # 先按是否吸烟分组，再分别查看小费比例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>total_bill</th>\n",
       "      <th>tip</th>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th>time</th>\n",
       "      <th>size</th>\n",
       "      <th>tip_pct</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">No</th>\n",
       "      <th>Fri</th>\n",
       "      <th>94</th>\n",
       "      <td>22.75</td>\n",
       "      <td>3.25</td>\n",
       "      <td>No</td>\n",
       "      <td>Fri</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.142857</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Sat</th>\n",
       "      <th>212</th>\n",
       "      <td>48.33</td>\n",
       "      <td>9.00</td>\n",
       "      <td>No</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>4</td>\n",
       "      <td>0.186220</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Sun</th>\n",
       "      <th>156</th>\n",
       "      <td>48.17</td>\n",
       "      <td>5.00</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>6</td>\n",
       "      <td>0.103799</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Thur</th>\n",
       "      <th>142</th>\n",
       "      <td>41.19</td>\n",
       "      <td>5.00</td>\n",
       "      <td>No</td>\n",
       "      <td>Thur</td>\n",
       "      <td>Lunch</td>\n",
       "      <td>5</td>\n",
       "      <td>0.121389</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">Yes</th>\n",
       "      <th>Fri</th>\n",
       "      <th>95</th>\n",
       "      <td>40.17</td>\n",
       "      <td>4.73</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Fri</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>4</td>\n",
       "      <td>0.117750</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Sat</th>\n",
       "      <th>170</th>\n",
       "      <td>50.81</td>\n",
       "      <td>10.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "      <td>0.196812</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Sun</th>\n",
       "      <th>182</th>\n",
       "      <td>45.35</td>\n",
       "      <td>3.50</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>3</td>\n",
       "      <td>0.077178</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Thur</th>\n",
       "      <th>197</th>\n",
       "      <td>43.11</td>\n",
       "      <td>5.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Thur</td>\n",
       "      <td>Lunch</td>\n",
       "      <td>4</td>\n",
       "      <td>0.115982</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 total_bill    tip smoker   day    time  size   tip_pct\n",
       "smoker day                                                             \n",
       "No     Fri  94        22.75   3.25     No   Fri  Dinner     2  0.142857\n",
       "       Sat  212       48.33   9.00     No   Sat  Dinner     4  0.186220\n",
       "       Sun  156       48.17   5.00     No   Sun  Dinner     6  0.103799\n",
       "       Thur 142       41.19   5.00     No  Thur   Lunch     5  0.121389\n",
       "Yes    Fri  95        40.17   4.73    Yes   Fri  Dinner     4  0.117750\n",
       "       Sat  170       50.81  10.00    Yes   Sat  Dinner     3  0.196812\n",
       "       Sun  182       45.35   3.50    Yes   Sun  Dinner     3  0.077178\n",
       "       Thur 197       43.11   5.00    Yes  Thur   Lunch     4  0.115982"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tips.groupby(['smoker', 'day']).apply(top, n=1, column='total_bill')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>min</th>\n",
       "      <th>25%</th>\n",
       "      <th>50%</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>smoker</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>No</th>\n",
       "      <td>151.0</td>\n",
       "      <td>0.159328</td>\n",
       "      <td>0.039910</td>\n",
       "      <td>0.056797</td>\n",
       "      <td>0.136906</td>\n",
       "      <td>0.155625</td>\n",
       "      <td>0.185014</td>\n",
       "      <td>0.291990</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Yes</th>\n",
       "      <td>93.0</td>\n",
       "      <td>0.163196</td>\n",
       "      <td>0.085119</td>\n",
       "      <td>0.035638</td>\n",
       "      <td>0.106771</td>\n",
       "      <td>0.153846</td>\n",
       "      <td>0.195059</td>\n",
       "      <td>0.710345</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        count      mean       std       min       25%       50%       75%  \\\n",
       "smoker                                                                      \n",
       "No      151.0  0.159328  0.039910  0.056797  0.136906  0.155625  0.185014   \n",
       "Yes      93.0  0.163196  0.085119  0.035638  0.106771  0.153846  0.195059   \n",
       "\n",
       "             max  \n",
       "smoker            \n",
       "No      0.291990  \n",
       "Yes     0.710345  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result = tips.groupby('smoker')['tip_pct'].describe()\n",
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "       smoker\n",
       "count  No        151.000000\n",
       "       Yes        93.000000\n",
       "mean   No          0.159328\n",
       "       Yes         0.163196\n",
       "std    No          0.039910\n",
       "       Yes         0.085119\n",
       "min    No          0.056797\n",
       "       Yes         0.035638\n",
       "25%    No          0.136906\n",
       "       Yes         0.106771\n",
       "50%    No          0.155625\n",
       "       Yes         0.153846\n",
       "75%    No          0.185014\n",
       "       Yes         0.195059\n",
       "max    No          0.291990\n",
       "       Yes         0.710345\n",
       "dtype: float64"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result.unstack('smoker') # 把列添加到索引，作用在smoker外。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>min</th>\n",
       "      <th>25%</th>\n",
       "      <th>50%</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>122.000000</td>\n",
       "      <td>0.161262</td>\n",
       "      <td>0.062514</td>\n",
       "      <td>0.046217</td>\n",
       "      <td>0.121838</td>\n",
       "      <td>0.154735</td>\n",
       "      <td>0.190036</td>\n",
       "      <td>0.501167</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>41.012193</td>\n",
       "      <td>0.002735</td>\n",
       "      <td>0.031968</td>\n",
       "      <td>0.014961</td>\n",
       "      <td>0.021309</td>\n",
       "      <td>0.001258</td>\n",
       "      <td>0.007103</td>\n",
       "      <td>0.295822</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>93.000000</td>\n",
       "      <td>0.159328</td>\n",
       "      <td>0.039910</td>\n",
       "      <td>0.035638</td>\n",
       "      <td>0.106771</td>\n",
       "      <td>0.153846</td>\n",
       "      <td>0.185014</td>\n",
       "      <td>0.291990</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>107.500000</td>\n",
       "      <td>0.160295</td>\n",
       "      <td>0.051212</td>\n",
       "      <td>0.040928</td>\n",
       "      <td>0.114305</td>\n",
       "      <td>0.154291</td>\n",
       "      <td>0.187525</td>\n",
       "      <td>0.396578</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>122.000000</td>\n",
       "      <td>0.161262</td>\n",
       "      <td>0.062514</td>\n",
       "      <td>0.046217</td>\n",
       "      <td>0.121838</td>\n",
       "      <td>0.154735</td>\n",
       "      <td>0.190036</td>\n",
       "      <td>0.501167</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>136.500000</td>\n",
       "      <td>0.162229</td>\n",
       "      <td>0.073817</td>\n",
       "      <td>0.051507</td>\n",
       "      <td>0.129372</td>\n",
       "      <td>0.155180</td>\n",
       "      <td>0.192547</td>\n",
       "      <td>0.605756</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>151.000000</td>\n",
       "      <td>0.163196</td>\n",
       "      <td>0.085119</td>\n",
       "      <td>0.056797</td>\n",
       "      <td>0.136906</td>\n",
       "      <td>0.155625</td>\n",
       "      <td>0.195059</td>\n",
       "      <td>0.710345</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            count      mean       std       min       25%       50%       75%  \\\n",
       "count    2.000000  2.000000  2.000000  2.000000  2.000000  2.000000  2.000000   \n",
       "mean   122.000000  0.161262  0.062514  0.046217  0.121838  0.154735  0.190036   \n",
       "std     41.012193  0.002735  0.031968  0.014961  0.021309  0.001258  0.007103   \n",
       "min     93.000000  0.159328  0.039910  0.035638  0.106771  0.153846  0.185014   \n",
       "25%    107.500000  0.160295  0.051212  0.040928  0.114305  0.154291  0.187525   \n",
       "50%    122.000000  0.161262  0.062514  0.046217  0.121838  0.154735  0.190036   \n",
       "75%    136.500000  0.162229  0.073817  0.051507  0.129372  0.155180  0.192547   \n",
       "max    151.000000  0.163196  0.085119  0.056797  0.136906  0.155625  0.195059   \n",
       "\n",
       "            max  \n",
       "count  2.000000  \n",
       "mean   0.501167  \n",
       "std    0.295822  \n",
       "min    0.291990  \n",
       "25%    0.396578  \n",
       "50%    0.501167  \n",
       "75%    0.605756  \n",
       "max    0.710345  "
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result.apply(lambda x: x.describe()) # result.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 禁止分组键"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>total_bill</th>\n",
       "      <th>tip</th>\n",
       "      <th>smoker</th>\n",
       "      <th>day</th>\n",
       "      <th>time</th>\n",
       "      <th>size</th>\n",
       "      <th>tip_pct</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>88</th>\n",
       "      <td>24.71</td>\n",
       "      <td>5.85</td>\n",
       "      <td>No</td>\n",
       "      <td>Thur</td>\n",
       "      <td>Lunch</td>\n",
       "      <td>2</td>\n",
       "      <td>0.236746</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>185</th>\n",
       "      <td>20.69</td>\n",
       "      <td>5.00</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>5</td>\n",
       "      <td>0.241663</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>51</th>\n",
       "      <td>10.29</td>\n",
       "      <td>2.60</td>\n",
       "      <td>No</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.252672</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149</th>\n",
       "      <td>7.51</td>\n",
       "      <td>2.00</td>\n",
       "      <td>No</td>\n",
       "      <td>Thur</td>\n",
       "      <td>Lunch</td>\n",
       "      <td>2</td>\n",
       "      <td>0.266312</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>232</th>\n",
       "      <td>11.61</td>\n",
       "      <td>3.39</td>\n",
       "      <td>No</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.291990</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>109</th>\n",
       "      <td>14.31</td>\n",
       "      <td>4.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.279525</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>183</th>\n",
       "      <td>23.17</td>\n",
       "      <td>6.50</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>4</td>\n",
       "      <td>0.280535</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>67</th>\n",
       "      <td>3.07</td>\n",
       "      <td>1.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sat</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>1</td>\n",
       "      <td>0.325733</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>178</th>\n",
       "      <td>9.60</td>\n",
       "      <td>4.00</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.416667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>172</th>\n",
       "      <td>7.25</td>\n",
       "      <td>5.15</td>\n",
       "      <td>Yes</td>\n",
       "      <td>Sun</td>\n",
       "      <td>Dinner</td>\n",
       "      <td>2</td>\n",
       "      <td>0.710345</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     total_bill   tip smoker   day    time  size   tip_pct\n",
       "88        24.71  5.85     No  Thur   Lunch     2  0.236746\n",
       "185       20.69  5.00     No   Sun  Dinner     5  0.241663\n",
       "51        10.29  2.60     No   Sun  Dinner     2  0.252672\n",
       "149        7.51  2.00     No  Thur   Lunch     2  0.266312\n",
       "232       11.61  3.39     No   Sat  Dinner     2  0.291990\n",
       "109       14.31  4.00    Yes   Sat  Dinner     2  0.279525\n",
       "183       23.17  6.50    Yes   Sun  Dinner     4  0.280535\n",
       "67         3.07  1.00    Yes   Sat  Dinner     1  0.325733\n",
       "178        9.60  4.00    Yes   Sun  Dinner     2  0.416667\n",
       "172        7.25  5.15    Yes   Sun  Dinner     2  0.710345"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tips.groupby('smoker', group_keys=False).apply(top) # 禁止构成多重索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 分位数和桶分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    (-1.98, -0.461]\n",
       "1    (-1.98, -0.461]\n",
       "2    (-1.98, -0.461]\n",
       "3    (-1.98, -0.461]\n",
       "4    (-1.98, -0.461]\n",
       "Name: data1, dtype: category\n",
       "Categories (4, interval[float64]): [(-3.505, -1.98] < (-1.98, -0.461] < (-0.461, 1.057] < (1.057, 2.576]]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frame = DataFrame({'data1': np.random.randn(1000),\n",
    "                   'data2': np.random.randn(1000)})\n",
    "factor = pd.cut(frame.data1, 4) # 切4份\n",
    "factor[:5] # 前5个元素所在区间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data1                 \n",
      "(-3.505, -1.98]  count     28.000000\n",
      "                 max        1.874309\n",
      "                 mean      -0.053760\n",
      "                 min       -2.035926\n",
      "(-1.98, -0.461]  count    302.000000\n",
      "                 max        2.475313\n",
      "                 mean      -0.009367\n",
      "                 min       -3.135844\n",
      "(-0.461, 1.057]  count    542.000000\n",
      "                 max        3.907300\n",
      "                 mean       0.043797\n",
      "                 min       -2.585936\n",
      "(1.057, 2.576]   count    128.000000\n",
      "                 max        2.491250\n",
      "                 mean       0.036609\n",
      "                 min       -2.149983\n",
      "Name: data2, dtype: float64\n",
      "                 count       max      mean       min\n",
      "data1                                               \n",
      "(-3.505, -1.98]   28.0  1.874309 -0.053760 -2.035926\n",
      "(-1.98, -0.461]  302.0  2.475313 -0.009367 -3.135844\n",
      "(-0.461, 1.057]  542.0  3.907300  0.043797 -2.585936\n",
      "(1.057, 2.576]   128.0  2.491250  0.036609 -2.149983\n"
     ]
    }
   ],
   "source": [
    "def get_stats(group):\n",
    "    return {'min': group.min(),\n",
    "             'max': group.max(),\n",
    "             'count': group.count(),\n",
    "             'mean': group.mean()}\n",
    "grouped = frame.data2.groupby(factor) # 根据data1的分段，对data2进行分组。\n",
    "result = grouped.apply(get_stats)\n",
    "print(result)\n",
    "print(result.unstack())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    B\n",
       "1    C\n",
       "2    B\n",
       "3    D\n",
       "4    C\n",
       "Name: data1, dtype: category\n",
       "Categories (10, object): [A < B < C < D ... G < H < I < J]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouping = pd.qcut(frame.data1, 10, labels=list('ABCDEFGHIJ')) # False的话就是默认数字编号\n",
    "grouping.head() # 返回每个元素的区间编号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "      <th>max</th>\n",
       "      <th>mean</th>\n",
       "      <th>min</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>data1</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.403635</td>\n",
       "      <td>-0.093973</td>\n",
       "      <td>-2.072895</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.300851</td>\n",
       "      <td>0.075512</td>\n",
       "      <td>-3.135844</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.475313</td>\n",
       "      <td>-0.052444</td>\n",
       "      <td>-2.599660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.269685</td>\n",
       "      <td>0.113117</td>\n",
       "      <td>-2.014964</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>E</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.800909</td>\n",
       "      <td>-0.045810</td>\n",
       "      <td>-1.898793</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F</th>\n",
       "      <td>100.0</td>\n",
       "      <td>3.263921</td>\n",
       "      <td>-0.000757</td>\n",
       "      <td>-2.036420</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>G</th>\n",
       "      <td>100.0</td>\n",
       "      <td>3.907300</td>\n",
       "      <td>0.188097</td>\n",
       "      <td>-2.585936</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>H</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.893293</td>\n",
       "      <td>-0.021765</td>\n",
       "      <td>-2.335397</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>I</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.491250</td>\n",
       "      <td>0.095277</td>\n",
       "      <td>-1.713401</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>J</th>\n",
       "      <td>100.0</td>\n",
       "      <td>2.291429</td>\n",
       "      <td>-0.016358</td>\n",
       "      <td>-2.149983</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       count       max      mean       min\n",
       "data1                                     \n",
       "A      100.0  2.403635 -0.093973 -2.072895\n",
       "B      100.0  2.300851  0.075512 -3.135844\n",
       "C      100.0  2.475313 -0.052444 -2.599660\n",
       "D      100.0  2.269685  0.113117 -2.014964\n",
       "E      100.0  2.800909 -0.045810 -1.898793\n",
       "F      100.0  3.263921 -0.000757 -2.036420\n",
       "G      100.0  3.907300  0.188097 -2.585936\n",
       "H      100.0  2.893293 -0.021765 -2.335397\n",
       "I      100.0  2.491250  0.095277 -1.713401\n",
       "J      100.0  2.291429 -0.016358 -2.149983"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped = frame.data2.groupby(grouping)\n",
    "grouped.apply(get_stats).unstack()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 示例：用特定于分组的值填充缺失值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    0.217070\n",
       "1   -0.489271\n",
       "2    0.217070\n",
       "3   -0.738455\n",
       "4    0.217070\n",
       "5    1.878936\n",
       "dtype: float64"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = Series(np.random.randn(6))\n",
    "s[::2] = np.nan\n",
    "s.fillna(s.mean()) # 用平均数填充缺失值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ohio         -1.622946\n",
       "New York     -0.393290\n",
       "Vermont            NaN\n",
       "Florida      -0.704855\n",
       "Oregon        0.249753\n",
       "Nevada             NaN\n",
       "California    0.074931\n",
       "Idaho              NaN\n",
       "dtype: float64"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "states = ['Ohio', 'New York', 'Vermont', 'Florida', 'Oregon', 'Nevada', 'California', 'Idaho']\n",
    "group_key = ['East'] * 4 + ['West'] * 4 # 前4个东部州，后4个西部州。\n",
    "data = Series(np.random.randn(8), index=states)\n",
    "data[['Vermont', 'Nevada', 'Idaho']] = np.nan\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "East   -0.907030\n",
       "West    0.162342\n",
       "dtype: float64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.groupby(group_key).mean() # 非NA求平均值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ohio         -1.622946\n",
       "New York     -0.393290\n",
       "Vermont      -0.907030\n",
       "Florida      -0.704855\n",
       "Oregon        0.249753\n",
       "Nevada        0.162342\n",
       "California    0.074931\n",
       "Idaho         0.162342\n",
       "dtype: float64"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fill_mean = lambda g: g.fillna(g.mean())\n",
    "data.groupby(group_key).apply(fill_mean) # 分组之后用每组的平均值填充"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ohio         -1.622946\n",
       "New York     -0.393290\n",
       "Vermont       0.500000\n",
       "Florida      -0.704855\n",
       "Oregon        0.249753\n",
       "Nevada       -1.000000\n",
       "California    0.074931\n",
       "Idaho        -1.000000\n",
       "dtype: float64"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fill_values = {'East': 0.5, 'West': -1} # 指定填充值\n",
    "fill_func = lambda g: g.fillna(fill_values[g.name])\n",
    "data.groupby(group_key).apply(fill_func)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 示例：随机采样和排列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AH    1\n",
       "2H    2\n",
       "3H    3\n",
       "4H    4\n",
       "5H    5\n",
       "dtype: int64"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 红桃（Hearts）、黑桃（Spades）、梅花（Clubs）、方片（Diamonds）\n",
    "suits = ['H', 'S', 'C', 'D']\n",
    "card_val = (list(range(1, 11)) + [10] * 3) * 4 # Python3下range是生成器，必须用list显示展开。\n",
    "base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q']\n",
    "cards = []\n",
    "for suit in ['H', 'S', 'C', 'D']:\n",
    "    cards.extend(str(num) + suit for num in base_names)\n",
    "deck = Series(card_val, index=cards)\n",
    "deck.head() # 牌面数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7C     7\n",
       "3D     3\n",
       "KH    10\n",
       "9D     9\n",
       "2C     2\n",
       "dtype: int64"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def draw(deck, n=5): # 随机抽n张\n",
    "    return deck.take(np.random.permutation(len(deck))[:n])\n",
    "draw(deck)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "C  JC    10\n",
       "   9C     9\n",
       "D  4D     4\n",
       "   JD    10\n",
       "H  5H     5\n",
       "   3H     3\n",
       "S  3S     3\n",
       "   8S     8\n",
       "dtype: int64"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 每种花色中随机抽取两张牌\n",
    "get_suit = lambda card: card[-1]\n",
    "deck.groupby(get_suit).apply(draw, n=2) # 默认根据索引排序，索引的最后一个字符是花色。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "JC     10\n",
       "10C    10\n",
       "JD     10\n",
       "4D      4\n",
       "9H      9\n",
       "10H    10\n",
       "AS      1\n",
       "10S    10\n",
       "dtype: int64"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "deck.groupby(get_suit, group_keys=False).apply(draw, n=2) # 效果一样，但是不用多重索引。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 示例：分组加权平均数和相关系数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>category</th>\n",
       "      <th>data</th>\n",
       "      <th>weights</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>a</td>\n",
       "      <td>1.592743</td>\n",
       "      <td>0.639899</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>a</td>\n",
       "      <td>0.046043</td>\n",
       "      <td>0.084863</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>a</td>\n",
       "      <td>-0.723238</td>\n",
       "      <td>0.214012</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>a</td>\n",
       "      <td>-0.738769</td>\n",
       "      <td>0.643120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>b</td>\n",
       "      <td>-0.149265</td>\n",
       "      <td>0.167864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>b</td>\n",
       "      <td>1.246441</td>\n",
       "      <td>0.884834</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>b</td>\n",
       "      <td>0.559904</td>\n",
       "      <td>0.594575</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>b</td>\n",
       "      <td>0.101432</td>\n",
       "      <td>0.923524</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  category      data   weights\n",
       "0        a  1.592743  0.639899\n",
       "1        a  0.046043  0.084863\n",
       "2        a -0.723238  0.214012\n",
       "3        a -0.738769  0.643120\n",
       "4        b -0.149265  0.167864\n",
       "5        b  1.246441  0.884834\n",
       "6        b  0.559904  0.594575\n",
       "7        b  0.101432  0.923524"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = DataFrame({'category': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'],\n",
    "                'data': np.random.randn(8),\n",
    "                'weights': np.random.rand(8)})\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "grouped = df.groupby('category')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "category\n",
       "a    0.248565\n",
       "b    0.585195\n",
       "dtype: float64"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_wavg = lambda g: np.average(g['data'], weights=g['weights']) # 求加权平均，weights自动归一化处理。\n",
    "grouped.apply(get_wavg) # 分组计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "DatetimeIndex: 5472 entries, 1990-02-01 to 2011-10-14\n",
      "Data columns (total 9 columns):\n",
      "AA      5472 non-null float64\n",
      "AAPL    5472 non-null float64\n",
      "GE      5472 non-null float64\n",
      "IBM     5472 non-null float64\n",
      "JNJ     5472 non-null float64\n",
      "MSFT    5472 non-null float64\n",
      "PEP     5471 non-null float64\n",
      "SPX     5472 non-null float64\n",
      "XOM     5472 non-null float64\n",
      "dtypes: float64(9)\n",
      "memory usage: 427.5 KB\n"
     ]
    }
   ],
   "source": [
    "close_px = pd.read_csv('../data/stock_px.csv', parse_dates=True, index_col=0)\n",
    "close_px.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>AA</th>\n",
       "      <th>AAPL</th>\n",
       "      <th>GE</th>\n",
       "      <th>IBM</th>\n",
       "      <th>JNJ</th>\n",
       "      <th>MSFT</th>\n",
       "      <th>PEP</th>\n",
       "      <th>SPX</th>\n",
       "      <th>XOM</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1990-02-01</th>\n",
       "      <td>4.98</td>\n",
       "      <td>7.86</td>\n",
       "      <td>2.87</td>\n",
       "      <td>16.79</td>\n",
       "      <td>4.27</td>\n",
       "      <td>0.51</td>\n",
       "      <td>6.04</td>\n",
       "      <td>328.79</td>\n",
       "      <td>6.12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1990-02-02</th>\n",
       "      <td>5.04</td>\n",
       "      <td>8.00</td>\n",
       "      <td>2.87</td>\n",
       "      <td>16.89</td>\n",
       "      <td>4.37</td>\n",
       "      <td>0.51</td>\n",
       "      <td>6.09</td>\n",
       "      <td>330.92</td>\n",
       "      <td>6.24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1990-02-05</th>\n",
       "      <td>5.07</td>\n",
       "      <td>8.18</td>\n",
       "      <td>2.87</td>\n",
       "      <td>17.32</td>\n",
       "      <td>4.34</td>\n",
       "      <td>0.51</td>\n",
       "      <td>6.05</td>\n",
       "      <td>331.85</td>\n",
       "      <td>6.25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1990-02-06</th>\n",
       "      <td>5.01</td>\n",
       "      <td>8.12</td>\n",
       "      <td>2.88</td>\n",
       "      <td>17.56</td>\n",
       "      <td>4.32</td>\n",
       "      <td>0.51</td>\n",
       "      <td>6.15</td>\n",
       "      <td>329.66</td>\n",
       "      <td>6.23</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1990-02-07</th>\n",
       "      <td>5.04</td>\n",
       "      <td>7.77</td>\n",
       "      <td>2.91</td>\n",
       "      <td>17.93</td>\n",
       "      <td>4.38</td>\n",
       "      <td>0.51</td>\n",
       "      <td>6.17</td>\n",
       "      <td>333.75</td>\n",
       "      <td>6.33</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              AA  AAPL    GE    IBM   JNJ  MSFT   PEP     SPX   XOM\n",
       "1990-02-01  4.98  7.86  2.87  16.79  4.27  0.51  6.04  328.79  6.12\n",
       "1990-02-02  5.04  8.00  2.87  16.89  4.37  0.51  6.09  330.92  6.24\n",
       "1990-02-05  5.07  8.18  2.87  17.32  4.34  0.51  6.05  331.85  6.25\n",
       "1990-02-06  5.01  8.12  2.88  17.56  4.32  0.51  6.15  329.66  6.23\n",
       "1990-02-07  5.04  7.77  2.91  17.93  4.38  0.51  6.17  333.75  6.33"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "close_px.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>AA</th>\n",
       "      <th>AAPL</th>\n",
       "      <th>GE</th>\n",
       "      <th>IBM</th>\n",
       "      <th>JNJ</th>\n",
       "      <th>MSFT</th>\n",
       "      <th>PEP</th>\n",
       "      <th>SPX</th>\n",
       "      <th>XOM</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1990</th>\n",
       "      <td>0.595024</td>\n",
       "      <td>0.545067</td>\n",
       "      <td>0.752187</td>\n",
       "      <td>0.738361</td>\n",
       "      <td>0.801145</td>\n",
       "      <td>0.586691</td>\n",
       "      <td>0.783168</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.517586</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1991</th>\n",
       "      <td>0.453574</td>\n",
       "      <td>0.365315</td>\n",
       "      <td>0.759607</td>\n",
       "      <td>0.557046</td>\n",
       "      <td>0.646401</td>\n",
       "      <td>0.524225</td>\n",
       "      <td>0.641775</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.569335</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1992</th>\n",
       "      <td>0.398180</td>\n",
       "      <td>0.498732</td>\n",
       "      <td>0.632685</td>\n",
       "      <td>0.262232</td>\n",
       "      <td>0.515740</td>\n",
       "      <td>0.492345</td>\n",
       "      <td>0.473871</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.318408</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1993</th>\n",
       "      <td>0.259069</td>\n",
       "      <td>0.238578</td>\n",
       "      <td>0.447257</td>\n",
       "      <td>0.211269</td>\n",
       "      <td>0.451503</td>\n",
       "      <td>0.425377</td>\n",
       "      <td>0.385089</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.318952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1994</th>\n",
       "      <td>0.428549</td>\n",
       "      <td>0.268420</td>\n",
       "      <td>0.572996</td>\n",
       "      <td>0.385162</td>\n",
       "      <td>0.372962</td>\n",
       "      <td>0.436585</td>\n",
       "      <td>0.450516</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.395078</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1995</th>\n",
       "      <td>0.291532</td>\n",
       "      <td>0.161829</td>\n",
       "      <td>0.519126</td>\n",
       "      <td>0.416390</td>\n",
       "      <td>0.315733</td>\n",
       "      <td>0.453660</td>\n",
       "      <td>0.413144</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.368752</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1996</th>\n",
       "      <td>0.292344</td>\n",
       "      <td>0.191482</td>\n",
       "      <td>0.750724</td>\n",
       "      <td>0.388497</td>\n",
       "      <td>0.569232</td>\n",
       "      <td>0.564015</td>\n",
       "      <td>0.421477</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.538736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1997</th>\n",
       "      <td>0.564427</td>\n",
       "      <td>0.211435</td>\n",
       "      <td>0.827512</td>\n",
       "      <td>0.646823</td>\n",
       "      <td>0.703538</td>\n",
       "      <td>0.606171</td>\n",
       "      <td>0.509344</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.695653</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1998</th>\n",
       "      <td>0.533802</td>\n",
       "      <td>0.379883</td>\n",
       "      <td>0.815243</td>\n",
       "      <td>0.623982</td>\n",
       "      <td>0.591988</td>\n",
       "      <td>0.698773</td>\n",
       "      <td>0.494213</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.369264</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999</th>\n",
       "      <td>0.099033</td>\n",
       "      <td>0.425584</td>\n",
       "      <td>0.710928</td>\n",
       "      <td>0.486167</td>\n",
       "      <td>0.517061</td>\n",
       "      <td>0.631315</td>\n",
       "      <td>0.336593</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.315383</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000</th>\n",
       "      <td>0.265359</td>\n",
       "      <td>0.440161</td>\n",
       "      <td>0.610362</td>\n",
       "      <td>0.445114</td>\n",
       "      <td>0.189765</td>\n",
       "      <td>0.538005</td>\n",
       "      <td>0.077525</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.084163</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001</th>\n",
       "      <td>0.624069</td>\n",
       "      <td>0.577152</td>\n",
       "      <td>0.794632</td>\n",
       "      <td>0.696038</td>\n",
       "      <td>0.111493</td>\n",
       "      <td>0.696447</td>\n",
       "      <td>0.133975</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.336869</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2002</th>\n",
       "      <td>0.747905</td>\n",
       "      <td>0.580306</td>\n",
       "      <td>0.822336</td>\n",
       "      <td>0.716833</td>\n",
       "      <td>0.585058</td>\n",
       "      <td>0.784607</td>\n",
       "      <td>0.487370</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.760069</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2003</th>\n",
       "      <td>0.690466</td>\n",
       "      <td>0.545582</td>\n",
       "      <td>0.777643</td>\n",
       "      <td>0.741775</td>\n",
       "      <td>0.562399</td>\n",
       "      <td>0.750534</td>\n",
       "      <td>0.541487</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.662775</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2004</th>\n",
       "      <td>0.591485</td>\n",
       "      <td>0.374283</td>\n",
       "      <td>0.728626</td>\n",
       "      <td>0.601740</td>\n",
       "      <td>0.354690</td>\n",
       "      <td>0.588531</td>\n",
       "      <td>0.466854</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.557742</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005</th>\n",
       "      <td>0.564267</td>\n",
       "      <td>0.467540</td>\n",
       "      <td>0.675637</td>\n",
       "      <td>0.516846</td>\n",
       "      <td>0.444728</td>\n",
       "      <td>0.562374</td>\n",
       "      <td>0.489559</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.631010</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2006</th>\n",
       "      <td>0.487638</td>\n",
       "      <td>0.428267</td>\n",
       "      <td>0.612388</td>\n",
       "      <td>0.598636</td>\n",
       "      <td>0.394026</td>\n",
       "      <td>0.406126</td>\n",
       "      <td>0.335054</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.518514</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2007</th>\n",
       "      <td>0.642427</td>\n",
       "      <td>0.508118</td>\n",
       "      <td>0.796945</td>\n",
       "      <td>0.603906</td>\n",
       "      <td>0.568423</td>\n",
       "      <td>0.658770</td>\n",
       "      <td>0.651911</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.786264</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2008</th>\n",
       "      <td>0.781057</td>\n",
       "      <td>0.681434</td>\n",
       "      <td>0.777337</td>\n",
       "      <td>0.833074</td>\n",
       "      <td>0.801005</td>\n",
       "      <td>0.804626</td>\n",
       "      <td>0.709264</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.828303</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009</th>\n",
       "      <td>0.735642</td>\n",
       "      <td>0.707103</td>\n",
       "      <td>0.713086</td>\n",
       "      <td>0.684513</td>\n",
       "      <td>0.603146</td>\n",
       "      <td>0.654902</td>\n",
       "      <td>0.541474</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.797921</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010</th>\n",
       "      <td>0.745700</td>\n",
       "      <td>0.710105</td>\n",
       "      <td>0.822285</td>\n",
       "      <td>0.783638</td>\n",
       "      <td>0.689896</td>\n",
       "      <td>0.730118</td>\n",
       "      <td>0.626655</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.839057</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2011</th>\n",
       "      <td>0.882045</td>\n",
       "      <td>0.691931</td>\n",
       "      <td>0.864595</td>\n",
       "      <td>0.802730</td>\n",
       "      <td>0.752379</td>\n",
       "      <td>0.800996</td>\n",
       "      <td>0.592029</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.859975</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            AA      AAPL        GE       IBM       JNJ      MSFT       PEP  \\\n",
       "1990  0.595024  0.545067  0.752187  0.738361  0.801145  0.586691  0.783168   \n",
       "1991  0.453574  0.365315  0.759607  0.557046  0.646401  0.524225  0.641775   \n",
       "1992  0.398180  0.498732  0.632685  0.262232  0.515740  0.492345  0.473871   \n",
       "1993  0.259069  0.238578  0.447257  0.211269  0.451503  0.425377  0.385089   \n",
       "1994  0.428549  0.268420  0.572996  0.385162  0.372962  0.436585  0.450516   \n",
       "1995  0.291532  0.161829  0.519126  0.416390  0.315733  0.453660  0.413144   \n",
       "1996  0.292344  0.191482  0.750724  0.388497  0.569232  0.564015  0.421477   \n",
       "1997  0.564427  0.211435  0.827512  0.646823  0.703538  0.606171  0.509344   \n",
       "1998  0.533802  0.379883  0.815243  0.623982  0.591988  0.698773  0.494213   \n",
       "1999  0.099033  0.425584  0.710928  0.486167  0.517061  0.631315  0.336593   \n",
       "2000  0.265359  0.440161  0.610362  0.445114  0.189765  0.538005  0.077525   \n",
       "2001  0.624069  0.577152  0.794632  0.696038  0.111493  0.696447  0.133975   \n",
       "2002  0.747905  0.580306  0.822336  0.716833  0.585058  0.784607  0.487370   \n",
       "2003  0.690466  0.545582  0.777643  0.741775  0.562399  0.750534  0.541487   \n",
       "2004  0.591485  0.374283  0.728626  0.601740  0.354690  0.588531  0.466854   \n",
       "2005  0.564267  0.467540  0.675637  0.516846  0.444728  0.562374  0.489559   \n",
       "2006  0.487638  0.428267  0.612388  0.598636  0.394026  0.406126  0.335054   \n",
       "2007  0.642427  0.508118  0.796945  0.603906  0.568423  0.658770  0.651911   \n",
       "2008  0.781057  0.681434  0.777337  0.833074  0.801005  0.804626  0.709264   \n",
       "2009  0.735642  0.707103  0.713086  0.684513  0.603146  0.654902  0.541474   \n",
       "2010  0.745700  0.710105  0.822285  0.783638  0.689896  0.730118  0.626655   \n",
       "2011  0.882045  0.691931  0.864595  0.802730  0.752379  0.800996  0.592029   \n",
       "\n",
       "      SPX       XOM  \n",
       "1990  1.0  0.517586  \n",
       "1991  1.0  0.569335  \n",
       "1992  1.0  0.318408  \n",
       "1993  1.0  0.318952  \n",
       "1994  1.0  0.395078  \n",
       "1995  1.0  0.368752  \n",
       "1996  1.0  0.538736  \n",
       "1997  1.0  0.695653  \n",
       "1998  1.0  0.369264  \n",
       "1999  1.0  0.315383  \n",
       "2000  1.0  0.084163  \n",
       "2001  1.0  0.336869  \n",
       "2002  1.0  0.760069  \n",
       "2003  1.0  0.662775  \n",
       "2004  1.0  0.557742  \n",
       "2005  1.0  0.631010  \n",
       "2006  1.0  0.518514  \n",
       "2007  1.0  0.786264  \n",
       "2008  1.0  0.828303  \n",
       "2009  1.0  0.797921  \n",
       "2010  1.0  0.839057  \n",
       "2011  1.0  0.859975  "
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rets = close_px.pct_change().dropna() # 扔掉有空数据的行\n",
    "spx_corr = lambda x: x.corrwith(x['SPX']) # 与SPX的相关系数\n",
    "by_year = rets.groupby(lambda x: x.year) # 指定用那个函数去做group\n",
    "by_year.apply(spx_corr) # 按年分组并计算与SPX的相关系数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1990    0.408271\n",
       "1991    0.266807\n",
       "1992    0.450592\n",
       "1993    0.236917\n",
       "1994    0.361638\n",
       "1995    0.258642\n",
       "1996    0.147539\n",
       "1997    0.196144\n",
       "1998    0.364106\n",
       "1999    0.329484\n",
       "2000    0.275298\n",
       "2001    0.563156\n",
       "2002    0.571095\n",
       "2003    0.486262\n",
       "2004    0.259024\n",
       "2005    0.300093\n",
       "2006    0.161735\n",
       "2007    0.417738\n",
       "2008    0.611901\n",
       "2009    0.432738\n",
       "2010    0.571946\n",
       "2011    0.581987\n",
       "dtype: float64"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "by_year.apply(lambda g: g['AAPL'].corr(g['MSFT'])) # 计算两个股票之间的相关系数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 示例：面向分组的线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>SPX</th>\n",
       "      <th>intercept</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1990</th>\n",
       "      <td>1.512772</td>\n",
       "      <td>0.001395</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1991</th>\n",
       "      <td>1.187351</td>\n",
       "      <td>0.000396</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1992</th>\n",
       "      <td>1.832427</td>\n",
       "      <td>0.000164</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1993</th>\n",
       "      <td>1.390470</td>\n",
       "      <td>-0.002657</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1994</th>\n",
       "      <td>1.190277</td>\n",
       "      <td>0.001617</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1995</th>\n",
       "      <td>0.858818</td>\n",
       "      <td>-0.001423</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1996</th>\n",
       "      <td>0.829389</td>\n",
       "      <td>-0.001791</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1997</th>\n",
       "      <td>0.749928</td>\n",
       "      <td>-0.001901</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1998</th>\n",
       "      <td>1.164582</td>\n",
       "      <td>0.004075</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999</th>\n",
       "      <td>1.384989</td>\n",
       "      <td>0.003273</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000</th>\n",
       "      <td>1.733802</td>\n",
       "      <td>-0.002523</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001</th>\n",
       "      <td>1.676128</td>\n",
       "      <td>0.003122</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2002</th>\n",
       "      <td>1.080330</td>\n",
       "      <td>-0.000199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2003</th>\n",
       "      <td>1.187770</td>\n",
       "      <td>0.000690</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2004</th>\n",
       "      <td>1.363463</td>\n",
       "      <td>0.004201</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005</th>\n",
       "      <td>1.766415</td>\n",
       "      <td>0.003246</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2006</th>\n",
       "      <td>1.645496</td>\n",
       "      <td>0.000080</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2007</th>\n",
       "      <td>1.198761</td>\n",
       "      <td>0.003438</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2008</th>\n",
       "      <td>0.968016</td>\n",
       "      <td>-0.001110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009</th>\n",
       "      <td>0.879103</td>\n",
       "      <td>0.002954</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010</th>\n",
       "      <td>1.052608</td>\n",
       "      <td>0.001261</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2011</th>\n",
       "      <td>0.806605</td>\n",
       "      <td>0.001514</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           SPX  intercept\n",
       "1990  1.512772   0.001395\n",
       "1991  1.187351   0.000396\n",
       "1992  1.832427   0.000164\n",
       "1993  1.390470  -0.002657\n",
       "1994  1.190277   0.001617\n",
       "1995  0.858818  -0.001423\n",
       "1996  0.829389  -0.001791\n",
       "1997  0.749928  -0.001901\n",
       "1998  1.164582   0.004075\n",
       "1999  1.384989   0.003273\n",
       "2000  1.733802  -0.002523\n",
       "2001  1.676128   0.003122\n",
       "2002  1.080330  -0.000199\n",
       "2003  1.187770   0.000690\n",
       "2004  1.363463   0.004201\n",
       "2005  1.766415   0.003246\n",
       "2006  1.645496   0.000080\n",
       "2007  1.198761   0.003438\n",
       "2008  0.968016  -0.001110\n",
       "2009  0.879103   0.002954\n",
       "2010  1.052608   0.001261\n",
       "2011  0.806605   0.001514"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def regress(data, yvar, xvars):\n",
    "    y= data[yvar]\n",
    "    x = data[xvars]\n",
    "    x['intercept'] = 1.\n",
    "    result = sm.OLS(y, x).fit()\n",
    "    return result.params\n",
    "\n",
    "by_year.apply(regress, 'AAPL', ['SPX'])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
